﻿using GuardMonitor.Model;
using GuardMonitor.Utils;
using Newtonsoft.Json.Linq;
using SmartWeighMonitor;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using 新门禁.Utils;
using 门禁系统.ViewModel;

namespace 新门禁
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {

        MainViewModel mainViewModel;
        MainWindow mainWindow;
        private DispatcherTimer timer;

        System.Windows.Forms.PictureBox m_pictureBox01;
        System.Windows.Forms.PictureBox m_pictureBox02;
        private int m_nPlayHandle01 = 0;
        private int m_nPlayHandle02 = 0;
        SynchronizationContext _syncContext = null;

        delegate void MyDelegate(Object value);
        private VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK m_PlateResultCB = null;
        private VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK m_PlateResultCB2 = null;
        private VzClientSDK.VZLPRC_GPIO_RECV_CALLBACK m_gpio_recvCB = null;

        private string m_sAppPath;

        public MainWindow()
        {
            InitializeComponent();
            _syncContext = SynchronizationContext.Current;
            m_sAppPath = System.IO.Directory.GetCurrentDirectory();
            mainViewModel = new MainViewModel();
            this.DataContext = mainViewModel;

            m_pictureBox01 = new System.Windows.Forms.PictureBox();
            m_pictureBox02 = new System.Windows.Forms.PictureBox();
            videoHost01.Child = m_pictureBox01;
            videoHost02.Child = m_pictureBox02;

            mainWindow = this;
            this.Loaded += Window_Loaded;
            int seconds = App.GetBaseInfo().RefreshSeconds;
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(seconds);
            timer.Tick += new EventHandler(timeCycle);
            timer.Start();
            //LogHelper.WriteInfoLog("测试");
        }



        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            version.Text = "门禁系统 ver.1.0.1";
            VzClientSDK.VzLPRClient_Setup();
            m_gpio_recvCB = new VzClientSDK.VZLPRC_GPIO_RECV_CALLBACK(OnGPIORecv);

            HttpServer server = App.GetHttpServer();
            if (null != server)
            {
                HttpServer.sendMsgEvent += Server_sendMsgEvent;
            }
            //LoadData();
            if (!"".Equals(App.GetBaseInfo().Camera_In_VideoUrl))
            {
                String[] videoInfoArray = App.GetBaseInfo().Camera_In_VideoUrl.Split(',');

                payVideo(1, m_pictureBox01, videoInfoArray);
            }
            if (!"".Equals(App.GetBaseInfo().Camera_Out_VideoUrl))
            {
                String[] videoInfoArray = App.GetBaseInfo().Camera_Out_VideoUrl.Split(',');

                payVideo(2, m_pictureBox02, videoInfoArray);
            }

            LoadData();
            //if (null != server)
            //{
            //    HttpServer.sendVideoEvent += Server_sendScreenEvent;
            //}

        }
        private void OnGPIORecv(int handle, int nGPIOId, int nVal, IntPtr pUserData)
        {
            int value = nVal;
        }
        //private void Server_sendScreenEvent(object msg)
        //{
        //    MyDelegate dele2 = new MyDelegate(DealVideoMessage);
        //    this.Dispatcher.Invoke(dele2, msg);
        //}

        void DealVideoMessage(object obj)
        {
            m_PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);

        }

        private int OnPlateResult(int handle, IntPtr pUserData,
                                                  IntPtr pResult, uint uNumPlates,
                                                  VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType,
                                                  IntPtr pImgFull,
                                                  IntPtr pImgPlateClip)
        {
            if (eResultType != VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_REALTIME)
            {
                VzClientSDK.TH_PlateResult result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult));
                string strLicense = new string(result.license);

                VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInfo = new VzClientSDK.VZ_LPR_MSG_PLATE_INFO();
                plateInfo.plate = strLicense;

                DateTime now = DateTime.Now;
                string sTime = string.Format("{0:yyyyMMddHHmmssffff}", now);

                string strFilePath = m_sAppPath + "\\in\\";
                if (!Directory.Exists(strFilePath))
                {
                    Directory.CreateDirectory(strFilePath);
                }
                string carNumber = strLicense.Substring(0, 7);
                string path = strFilePath + sTime+ carNumber + ".jpg";

                VzClientSDK.VzLPRClient_ImageSaveToJpeg(pImgFull, path, 100);
                plateInfo.img_path = path;

                int size = Marshal.SizeOf(plateInfo);
                IntPtr intptr = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(plateInfo, intptr, true);

                //Win32API.PostMessage(hwndMain, MSG_PLATE_INFO, (int)intptr, handle);
            }

            return 0;
        }
        private int OnPlateResult2(int handle, IntPtr pUserData,
                                                  IntPtr pResult, uint uNumPlates,
                                                  VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType,
                                                  IntPtr pImgFull,
                                                  IntPtr pImgPlateClip)
        {
            if (eResultType != VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_REALTIME)
            {
                VzClientSDK.TH_PlateResult result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult));
                string strLicense = new string(result.license);

                VzClientSDK.VZ_LPR_MSG_PLATE_INFO plateInfo = new VzClientSDK.VZ_LPR_MSG_PLATE_INFO();
                plateInfo.plate = strLicense;

                DateTime now = DateTime.Now;
                string sTime = string.Format("{0:yyyyMMddHHmmssffff}", now);

                string strFilePath = m_sAppPath + "\\out\\";
                if (!Directory.Exists(strFilePath))
                {
                    Directory.CreateDirectory(strFilePath);
                }
                string carNumber = strLicense.Substring(0, 7);

                string path = strFilePath + sTime+ carNumber + ".jpg";

                VzClientSDK.VzLPRClient_ImageSaveToJpeg(pImgFull, path, 100);
                plateInfo.img_path = path;

                int size = Marshal.SizeOf(plateInfo);
                IntPtr intptr = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(plateInfo, intptr, true);

                //Win32API.PostMessage(hwndMain, MSG_PLATE_INFO, (int)intptr, handle);
            }

            return 0;
        }
        private void payVideo(int idx, System.Windows.Forms.PictureBox picBox, String[] info)
        {
            string ip = info[0];
            short nPort = Int16.Parse(info[1]);
            string username = info[2];
            string pass = info[3];

            int handle = 0;
            handle = VzClientSDK.VzLPRClient_Open(ip, (ushort)nPort, username, pass);
            if (handle == 0)
            {
                return;
            }
            VzClientSDK.VzLPRClient_SetIsShowPlateRect(handle, 0);
            picBox.Image = null;
            if (idx == 1)
            {
                if (m_nPlayHandle01 > 0)
                {
                    VzClientSDK.VzLPRClient_StopRealPlay(m_nPlayHandle01);
                    m_nPlayHandle01 = 0;
                }
            }
            else if (idx == 2)
            {
                if (m_nPlayHandle02 > 0)
                {
                    VzClientSDK.VzLPRClient_StopRealPlay(m_nPlayHandle02);
                    m_nPlayHandle02 = 0;
                }
            }
            VzClientSDK.VzLPRClient_SetVideoVBR(handle, 5);
            int lprHandle1 = 0;
            if (picBox.Tag != null)
            {
                string sHandle = picBox.Tag.ToString();
                lprHandle1 = Int32.Parse(sHandle);
            }
            if (lprHandle1 > 0)
            {
                VzClientSDK.VzLPRClient_SetPlateInfoCallBack(lprHandle1, null, IntPtr.Zero, 0);
            }
            if (idx == 1)
            {
                m_nPlayHandle01 = VzClientSDK.VzLPRClient_StartRealPlay(handle, picBox.Handle);
                picBox.Tag = handle;
                m_PlateResultCB = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
                VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, m_PlateResultCB, IntPtr.Zero, 1);
                VzClientSDK.VzLPRClient_SetGPIORecvCallBack(handle, m_gpio_recvCB, IntPtr.Zero);


            }
            else if (idx == 2)
            {
                m_nPlayHandle02 = VzClientSDK.VzLPRClient_StartRealPlay(handle, picBox.Handle);
                picBox.Tag = handle;
                m_PlateResultCB2 = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult2);
                VzClientSDK.VzLPRClient_SetPlateInfoCallBack(handle, m_PlateResultCB2, IntPtr.Zero, 1);
            }
        }

        private void LoadData()
        {
            //new Task(() =>
            //{
            //    Invoke();
            //}).Start();

            new Task(() =>
            {
                getAccessList();
            }).Start();
        }

        private async void Invoke()
        {
            try
            {
                String gateCode = App.GetBaseInfo().gateCode;
                String[] gatecodes= gateCode.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                String ip = App.GetBaseInfo().HttpServerIp;
                String port = App.GetBaseInfo().HttpServerPort;
                //String port = App.GetBaseInfo().AuthHttpServerPort;
                JArray jArray = new JArray();
                for (int i = 0; i < gatecodes.Length; i++)
                {
                    JObject json = new JObject();
                    //json.Add("gateCode",gatecodes[i]);
                    json.Add("id",gatecodes[i]);
                    jArray.Add(json);
                }
                //String bodyJsonStr = "{\"gateCode\":\"" + gateCode + "\"}";
                JObject newJson=new JObject();
                newJson.Add("jsonList", jArray);
                  var result = HttpPostHelper.doHttpAsyncPost("http://" + ip + ":" + port + "/qd-s-factory/accessLists", newJson.ToString());
                ///qd-s-factory/access/accessList
               // var result = HttpPostHelper.doHttpAsyncPost("http://" + ip + ":" + port + "/qd-s-factory/access/accessList", newJson.ToString());
                string str = await result;  //等待返回

                MyDelegate d = new MyDelegate(dealLoadData);
                this.Dispatcher.Invoke(d, str);
            }
            catch (Exception ex) {
                LogObject.WriteLog(ex.ToString(), "Message");

            }
        }
        private async void getAccessList()
        {
            try
            {
                String gateCode = App.GetBaseInfo().gateCode;
                String[] gatecodes = gateCode.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                String ip = App.GetBaseInfo().HttpServerIp;
                String port = App.GetBaseInfo().HttpServerPort;
                //String port = App.GetBaseInfo().AuthHttpServerPort;
                JArray jArray = new JArray();
                for (int i = 0; i < gatecodes.Length; i++)
                {
                    JObject json = new JObject();
                    //json.Add("gateCode", gatecodes[i]);
                    json.Add("id", gatecodes[i]);
                    jArray.Add(json);
                }
                //String bodyJsonStr = "{\"gateCode\":\"" + gateCode + "\"}";
                JObject newJson = new JObject();
                newJson.Add("jsonList", jArray);
                var result = HttpPostHelper.doHttpAsyncPost("http://" + ip + ":" + port + "/qd-s-factory/accessLists", newJson.ToString());
                //var result = HttpPostHelper.doHttpAsyncPost("http://" + ip + ":" + port + "/qd-s-factory/access/accessList", newJson.ToString());
                String msg = await result;
                JObject respJson = JObject.Parse(msg);
                String status = respJson["success"].ToString();
                if ("true".Equals(status.ToLower()))
                {
                    _syncContext.Post(SetDataLists, respJson);

                }
            }
            catch (Exception ex)
            {
                LogObject.WriteLog(ex.ToString(), "Message");

            }
        }

        private void SetDataLists(object obj)
        {
            string flag = App.GetBaseInfo().ButtonLimit;
            try
            {

                JObject jsonObj = obj as JObject;
                bool success = (bool)jsonObj.GetValue("success");
                if (!success) return;
                int idx = 0;
                mainViewModel.carInList.Clear();
                JObject dataObj = (JObject)jsonObj.GetValue("data");
                JArray waitInArray = (JArray)dataObj.GetValue("willInList");
                String check = (String)jsonObj.GetValue("check");


                idx = 0;
                foreach (JObject item in waitInArray)
                {
                    idx++;
                    Record record = getRecordByJSON(item);
                    record.xh = idx.ToString();
                    if (flag.Equals("1"))
                    {
                        record.Visibility = "Visible";
                    }
                    else
                    {
                        record.Visibility = "Hidden";
                    }

                    if (flag.Equals("1"))
                    {
                        record.checkVisibility = "Visible";
                    }
                    else
                    {
                        record.checkVisibility = "Hidden";

                    }
                    mainViewModel.carInList.Add(record);
                }

                mainViewModel.carInList2.Clear();
                idx = 0;
                JArray hasInArray = (JArray)dataObj.GetValue("inList");
                foreach (JObject item in hasInArray)
                {
                    idx++;
                    Record record = getRecordByJSON(item);
                    record.xh = idx.ToString();
                    mainViewModel.carInList2.Add(record);
                }

                mainViewModel.carOutList.Clear();
                idx = 0;
                JArray waitOutArray = (JArray)dataObj.GetValue("willOutList");
                foreach (JObject item in waitOutArray)
                {
                    idx++;
                    Record record = getRecordByJSON(item);
                    record.xh = idx.ToString();
                    if (flag.Equals("1"))
                    {
                        record.Visibility = "Visible";
                    }
                    else
                    {
                        record.Visibility = "Hidden";
                    }
                    mainViewModel.carOutList.Add(record);
                }

                mainViewModel.carOutList2.Clear();
                idx = 0;
                JArray hasOutArray = (JArray)dataObj.GetValue("outList");
                foreach (JObject item in hasOutArray)
                {
                    idx++;
                    Record record = getRecordByJSON(item);
                    record.xh = idx.ToString();
                    mainViewModel.carOutList2.Add(record);
                }
            }
            catch (Exception ex)
            {
                LogObject.WriteLog("send message: ", "loadData");

            }
        }
        public Record getRecordByJSON(JObject item)
        {
            Record record = new Record();
            record.id = (String)item.GetValue("id");
            record.xh = (String)item.GetValue("xh");
            record.carNo = (String)item.GetValue("carNo");
            record.invName = (String)item.GetValue("invName");
            record.orderNo = (String)item.GetValue("orderNo");
            record.cTime = (String)item.GetValue("cTime");

            String status = (String)item.GetValue("checkStatus");
            if (status.Equals("0"))
            {
                record.CheckStatus = "待安检";
            }
            else if (status.Equals("1"))
            {
                record.CheckStatus = "安检通过";
            }
            else
            {
                record.CheckStatus = "安检未通过";
            }



            return record;
        }

        void dealLoadData(Object obj)
        {
            //    JToken didoControl = App.GetGlobalVariablesModel().DIDOControl;
            //    LogObject.WriteLog("send message: " + didoControl, "didoControl");

            //    JToken[] jTokens = didoControl.ToArray();
            //    int tips1 = 0;
            //    int tips2 = 0;
            //    for (int i = 0; i < jTokens.Length; i++)
            //    {
            //        //menuButton = jTokens[i].ToString();
            //        if (jTokens[i].ToString().Equals("WPF_DIDO"))
            //        {
            //            tips1 = 1;

            //        }
            //        else if (jTokens[i].ToString().Equals("WPF_CHECK"))
            //        {
            //            tips2 = 1;


            //        }

            //    }         
            //JObject msgObj = (JObject)obj;
            //String check = (String)msgObj.GetValue("check");
            string buttonLimit = App.GetBaseInfo().ButtonLimit;

            mainViewModel.LoadData((string)obj,buttonLimit);
        }
        private void DGInList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
        }

        private void Server_sendMsgEvent(object msg)
        {
            MyDelegate dele = new MyDelegate(DealMessage);
            this.Dispatcher.Invoke(dele, msg);
        }

        void DealMessage(object obj)
        {
            JObject jsonObj = JObject.Parse(obj.ToString());
            String type = (String)jsonObj.GetValue("type");
            if ("GetCarNo".Equals(type))
            {
                JObject jsonDetail = (JObject)jsonObj.GetValue("detail");
                String inOut = (String)jsonDetail.GetValue("inOut");
                String carNo = (String)jsonDetail.GetValue("carNo");
                if ("in".Equals(inOut))
                {
                    txtInCarNo.Text = carNo;
                    txtInResult.Text = "";
                }
                else if ("out".Equals(inOut))
                {
                    txtOutCarNo.Text = carNo;
                    txtOutResult.Text = "";
                }
            }
            else if ("Check".Equals(type))
            {
                bool result = (bool)jsonObj.GetValue("result");
                String inOut = (String)jsonObj.GetValue("inOut");
                String message = (String)jsonObj.GetValue("message");

                if (result)
                {
                    if ("in".Equals(inOut))
                    {
                        txtInResult.Foreground = Brushes.Green;
                        txtInResult.Text = "正常放行";
                    }
                    else if ("out".Equals(inOut))
                    {
                        txtOutResult.Foreground = Brushes.Green;
                        txtOutResult.Text = "正常放行";
                    }
                    LoadData();
                }
                else
                {
                    if ("in".Equals(inOut))
                    {
                        txtInResult.Foreground = Brushes.Red;
                        txtInResult.Text = message;
                        //MessageBox.Show(message);
                       
                    }
                    else if ("out".Equals(inOut))
                    {
                        txtOutResult.Foreground = Brushes.Red;
                        txtOutResult.Text = message;
                        //MessageBox.Show(message);


                    }
                }
            }
        }

        private void timeCycle(object sender, EventArgs e)
        {
            LoadData();
        }

        public void doDataRefresh(object sender, RoutedEventArgs e)
        {
            LoadData();
        }

        private void showPassWindowIn(object sender, RoutedEventArgs e)
        {
            //int idx = DGInList.SelectedIndex;
            //if (idx != 0)
            //{
            //    MessageBox.Show("只能按排队顺序放行");
            //    return;
            //}
            Record record = (Record)DGInList.SelectedItem;

            PassWindow passWindow = new PassWindow();
            passWindow.setInOutType("in");
            passWindow.setCarNo(record.carNo);
            passWindow.Owner = mainWindow;

            bool result = (bool)passWindow.ShowDialog();
            if (result)
            {
                txtInCarNo.Text = record.carNo;
                txtInResult.Foreground = Brushes.Green;
                txtInResult.Text = "手动放行";
                LoadData();
            }
        }

        private void showPassWindowOut(object sender, RoutedEventArgs e)
        {
            //int idx = DGOutList.SelectedIndex;
            //if (idx != 0)
            //{
            //    MessageBox.Show("只能按排队顺序放行");
            //    return;
            //}

            Record record = (Record)DGOutList.SelectedItem;

            PassWindow passWindow = new PassWindow();
            passWindow.setInOutType("out");
            passWindow.setCarNo(record.carNo);
            passWindow.Owner = mainWindow;

            bool result = (bool)passWindow.ShowDialog();
            if (result)
            {
                txtOutCarNo.Text = record.carNo;
                txtOutResult.Foreground = Brushes.Green;
                txtOutResult.Text = "手动放行";
                LoadData();
            }
        }

        private void showCheckWindowIn(object sender, RoutedEventArgs e)
        {
            Record record = (Record)DGInList.SelectedItem;
            CheckWindow checkWindow = new CheckWindow();
            checkWindow.setBillNo(record.id);
            checkWindow.Owner = mainWindow;
            bool result = (bool)checkWindow.ShowDialog();
            if (result)
            {
                LoadData();
            }
        }

        private void DGOutList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        //private void videoTest(object sender, RoutedEventArgs e)
        //{
        //    JObject json = new JObject();
        //    DealVideoMessage(json);
        //}
    }
}
